package com.geo.content.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.Builder;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;

/**
 * 媒体文件实体类
 * 
 * @author GEO Team
 * @version 1.0
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("content_media_file")
public class MediaFile {
    
    // 手动添加builder方法以解决编译问题
    public static MediaFileBuilder builder() {
        return new MediaFileBuilder();
    }
    
    public static class MediaFileBuilder {
        private String id;
        private String contentId;
        private String merchantId;
        private String fileName;
        private String originalName;
        private String filePath;
        private String fileUrl;
        private FileType fileType;
        private String mimeType;
        private Long fileSize;
        private String fileHash;
        private FileStatus status;
        private String description;
        private String tags;
        private StorageLocation storageLocation;
        private String bucketName;
        private String extendedInfo;
        private String mediaInfo;
        private String thumbnailPath;
        private String thumbnailUrl;
        private ProcessStatus processStatus;
        private String processResult;
        private Long downloadCount;
        private Long accessCount;
        private LocalDateTime lastAccessedAt;
        private LocalDateTime expiresAt;
        private Boolean isPublic;
        private String remark;
        private LocalDateTime createdAt;
        private LocalDateTime updatedAt;
        private String createdBy;
        private String updatedBy;
        private Integer deleted;
        
        public MediaFileBuilder id(String id) {
            this.id = id;
            return this;
        }
        
        public MediaFileBuilder contentId(String contentId) {
            this.contentId = contentId;
            return this;
        }
        
        public MediaFileBuilder merchantId(String merchantId) {
            this.merchantId = merchantId;
            return this;
        }
        
        public MediaFileBuilder fileName(String fileName) {
            this.fileName = fileName;
            return this;
        }
        
        public MediaFileBuilder originalName(String originalName) {
            this.originalName = originalName;
            return this;
        }
        
        public MediaFileBuilder filePath(String filePath) {
            this.filePath = filePath;
            return this;
        }
        
        public MediaFileBuilder fileUrl(String fileUrl) {
            this.fileUrl = fileUrl;
            return this;
        }
        
        public MediaFileBuilder fileType(FileType fileType) {
            this.fileType = fileType;
            return this;
        }
        
        public MediaFileBuilder mimeType(String mimeType) {
            this.mimeType = mimeType;
            return this;
        }
        
        public MediaFileBuilder fileSize(Long fileSize) {
            this.fileSize = fileSize;
            return this;
        }
        
        public MediaFileBuilder fileHash(String fileHash) {
            this.fileHash = fileHash;
            return this;
        }
        
        public MediaFileBuilder status(FileStatus status) {
            this.status = status;
            return this;
        }
        
        public MediaFileBuilder description(String description) {
            this.description = description;
            return this;
        }
        
        public MediaFileBuilder tags(String tags) {
            this.tags = tags;
            return this;
        }
        
        public MediaFileBuilder storageLocation(StorageLocation storageLocation) {
            this.storageLocation = storageLocation;
            return this;
        }
        
        public MediaFileBuilder bucketName(String bucketName) {
            this.bucketName = bucketName;
            return this;
        }
        
        public MediaFileBuilder extendedInfo(String extendedInfo) {
            this.extendedInfo = extendedInfo;
            return this;
        }
        
        public MediaFileBuilder mediaInfo(String mediaInfo) {
            this.mediaInfo = mediaInfo;
            return this;
        }
        
        public MediaFileBuilder thumbnailPath(String thumbnailPath) {
            this.thumbnailPath = thumbnailPath;
            return this;
        }
        
        public MediaFileBuilder thumbnailUrl(String thumbnailUrl) {
            this.thumbnailUrl = thumbnailUrl;
            return this;
        }
        
        public MediaFileBuilder processStatus(ProcessStatus processStatus) {
            this.processStatus = processStatus;
            return this;
        }
        
        public MediaFileBuilder processResult(String processResult) {
            this.processResult = processResult;
            return this;
        }
        
        public MediaFileBuilder downloadCount(Long downloadCount) {
            this.downloadCount = downloadCount;
            return this;
        }
        
        public MediaFileBuilder accessCount(Long accessCount) {
            this.accessCount = accessCount;
            return this;
        }
        
        public MediaFileBuilder lastAccessedAt(LocalDateTime lastAccessedAt) {
            this.lastAccessedAt = lastAccessedAt;
            return this;
        }
        
        public MediaFileBuilder expiresAt(LocalDateTime expiresAt) {
            this.expiresAt = expiresAt;
            return this;
        }
        
        public MediaFileBuilder isPublic(Boolean isPublic) {
            this.isPublic = isPublic;
            return this;
        }
        
        public MediaFileBuilder remark(String remark) {
            this.remark = remark;
            return this;
        }
        
        public MediaFileBuilder createdAt(LocalDateTime createdAt) {
            this.createdAt = createdAt;
            return this;
        }
        
        public MediaFileBuilder updatedAt(LocalDateTime updatedAt) {
            this.updatedAt = updatedAt;
            return this;
        }
        
        public MediaFileBuilder createdBy(String createdBy) {
            this.createdBy = createdBy;
            return this;
        }
        
        public MediaFileBuilder updatedBy(String updatedBy) {
            this.updatedBy = updatedBy;
            return this;
        }
        
        public MediaFileBuilder deleted(Integer deleted) {
            this.deleted = deleted;
            return this;
        }
        
        public MediaFile build() {
            MediaFile mediaFile = new MediaFile();
            mediaFile.id = this.id;
            mediaFile.contentId = this.contentId;
            mediaFile.merchantId = this.merchantId;
            mediaFile.fileName = this.fileName;
            mediaFile.originalName = this.originalName;
            mediaFile.filePath = this.filePath;
            mediaFile.fileUrl = this.fileUrl;
            mediaFile.fileType = this.fileType;
            mediaFile.mimeType = this.mimeType;
            mediaFile.fileSize = this.fileSize;
            mediaFile.fileHash = this.fileHash;
            mediaFile.status = this.status;
            mediaFile.description = this.description;
            mediaFile.tags = this.tags;
            mediaFile.storageLocation = this.storageLocation;
            mediaFile.bucketName = this.bucketName;
            mediaFile.extendedInfo = this.extendedInfo;
            mediaFile.mediaInfo = this.mediaInfo;
            mediaFile.thumbnailPath = this.thumbnailPath;
            mediaFile.thumbnailUrl = this.thumbnailUrl;
            mediaFile.processStatus = this.processStatus;
            mediaFile.processResult = this.processResult;
            mediaFile.downloadCount = this.downloadCount;
            mediaFile.accessCount = this.accessCount;
            mediaFile.lastAccessedAt = this.lastAccessedAt;
            mediaFile.expiresAt = this.expiresAt;
            mediaFile.isPublic = this.isPublic;
            mediaFile.remark = this.remark;
            mediaFile.createdAt = this.createdAt;
            mediaFile.updatedAt = this.updatedAt;
            mediaFile.createdBy = this.createdBy;
            mediaFile.updatedBy = this.updatedBy;
            mediaFile.deleted = this.deleted;
            return mediaFile;
        }
    }
    
    /**
     * 文件ID
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;
    
    /**
     * 内容ID
     */
    @TableField("content_id")
    private String contentId;
    
    /**
     * 商家ID
     */
    @TableField("merchant_id")
    private String merchantId;
    
    /**
     * 文件名称
     */
    @NotBlank(message = "文件名称不能为空")
    @Size(max = 255, message = "文件名称长度不能超过255个字符")
    @TableField("file_name")
    private String fileName;
    
    /**
     * 原始文件名
     */
    @TableField("original_name")
    private String originalName;
    
    /**
     * 文件路径
     */
    @TableField("file_path")
    private String filePath;
    
    /**
     * 文件URL
     */
    @TableField("file_url")
    private String fileUrl;
    
    /**
     * 文件类型
     */
    @TableField("file_type")
    private FileType fileType;
    
    /**
     * MIME类型
     */
    @TableField("mime_type")
    private String mimeType;
    
    /**
     * 文件大小（字节）
     */
    @TableField("file_size")
    private Long fileSize;
    
    /**
     * 文件MD5哈希值
     */
    @TableField("file_hash")
    private String fileHash;
    
    /**
     * 文件状态
     */
    @TableField("status")
    private FileStatus status;
    
    /**
     * 文件描述
     */
    @TableField("description")
    private String description;
    
    /**
     * 文件标签（JSON格式）
     */
    @TableField("tags")
    private String tags;
    
    /**
     * 存储位置
     */
    @TableField("storage_location")
    private StorageLocation storageLocation;
    
    /**
     * 存储桶名称
     */
    @TableField("bucket_name")
    private String bucketName;
    
    /**
     * 文件扩展信息（JSON格式）
     */
    @TableField("extended_info")
    private String extendedInfo;
    
    /**
     * 媒体信息（JSON格式）- 包含分辨率、时长等
     */
    @TableField("media_info")
    private String mediaInfo;
    
    /**
     * 缩略图路径
     */
    @TableField("thumbnail_path")
    private String thumbnailPath;
    
    /**
     * 缩略图URL
     */
    @TableField("thumbnail_url")
    private String thumbnailUrl;
    
    /**
     * 处理状态
     */
    @TableField("process_status")
    private ProcessStatus processStatus;
    
    /**
     * 处理结果（JSON格式）
     */
    @TableField("process_result")
    private String processResult;
    
    /**
     * 下载次数
     */
    @TableField("download_count")
    private Long downloadCount;
    
    /**
     * 访问次数
     */
    @TableField("access_count")
    private Long accessCount;
    
    /**
     * 最后访问时间
     */
    @TableField("last_accessed_at")
    private LocalDateTime lastAccessedAt;
    
    /**
     * 过期时间
     */
    @TableField("expires_at")
    private LocalDateTime expiresAt;
    
    /**
     * 是否公开
     */
    @TableField("is_public")
    private Boolean isPublic;
    
    /**
     * 备注
     */
    @TableField("remark")
    private String remark;
    
    /**
     * 创建时间
     */
    @TableField(value = "created_at", fill = FieldFill.INSERT)
    private LocalDateTime createdAt;
    
    /**
     * 更新时间
     */
    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;
    
    /**
     * 创建者ID
     */
    @TableField("created_by")
    private String createdBy;
    
    /**
     * 更新者ID
     */
    @TableField("updated_by")
    private String updatedBy;
    
    /**
     * 逻辑删除标志
     */
    @TableLogic
    @TableField("deleted")
    private Integer deleted;
    
    /**
     * 文件类型枚举
     */
    public enum FileType {
        IMAGE("image", "图片"),
        VIDEO("video", "视频"),
        AUDIO("audio", "音频"),
        DOCUMENT("document", "文档"),
        ARCHIVE("archive", "压缩包"),
        OTHER("other", "其他");
        
        private final String code;
        private final String description;
        
        FileType(String code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
        
        public static FileType fromCode(String code) {
            for (FileType type : values()) {
                if (type.code.equals(code)) {
                    return type;
                }
            }
            return OTHER;
        }
        
        public static FileType fromMimeType(String mimeType) {
            if (mimeType == null) return OTHER;
            
            if (mimeType.startsWith("image/")) {
                return IMAGE;
            } else if (mimeType.startsWith("video/")) {
                return VIDEO;
            } else if (mimeType.startsWith("audio/")) {
                return AUDIO;
            } else if (mimeType.startsWith("application/pdf") || 
                       mimeType.startsWith("application/msword") ||
                       mimeType.startsWith("application/vnd.openxmlformats-officedocument")) {
                return DOCUMENT;
            } else if (mimeType.startsWith("application/zip") ||
                       mimeType.startsWith("application/x-rar") ||
                       mimeType.startsWith("application/x-7z")) {
                return ARCHIVE;
            }
            
            return OTHER;
        }
    }
    
    /**
     * 文件状态枚举
     */
    public enum FileStatus {
        UPLOADING("uploading", "上传中"),
        UPLOADED("uploaded", "已上传"),
        PROCESSING("processing", "处理中"),
        PROCESSED("processed", "已处理"),
        FAILED("failed", "处理失败"),
        DELETED("deleted", "已删除");
        
        private final String code;
        private final String description;
        
        FileStatus(String code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
        
        public static FileStatus fromCode(String code) {
            for (FileStatus status : values()) {
                if (status.code.equals(code)) {
                    return status;
                }
            }
            return UPLOADED;
        }
    }
    
    /**
     * 存储位置枚举
     */
    public enum StorageLocation {
        LOCAL("local", "本地存储"),
        MINIO("minio", "MinIO对象存储"),
        OSS("oss", "阿里云OSS"),
        COS("cos", "腾讯云COS"),
        AWS_S3("aws_s3", "AWS S3"),
        CDN("cdn", "CDN存储");
        
        private final String code;
        private final String description;
        
        StorageLocation(String code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
        
        public static StorageLocation fromCode(String code) {
            for (StorageLocation location : values()) {
                if (location.code.equals(code)) {
                    return location;
                }
            }
            return LOCAL;
        }
    }
    
    /**
     * 处理状态枚举
     */
    public enum ProcessStatus {
        PENDING("pending", "待处理"),
        PROCESSING("processing", "处理中"),
        COMPLETED("completed", "已完成"),
        FAILED("failed", "处理失败"),
        SKIPPED("skipped", "已跳过");
        
        private final String code;
        private final String description;
        
        ProcessStatus(String code, String description) {
            this.code = code;
            this.description = description;
        }
        
        public String getCode() {
            return code;
        }
        
        public String getDescription() {
            return description;
        }
        
        public static ProcessStatus fromCode(String code) {
            for (ProcessStatus status : values()) {
                if (status.code.equals(code)) {
                    return status;
                }
            }
            return PENDING;
        }
    }
    
    /**
     * 检查文件是否可访问
     * @return 是否可访问
     */
    public boolean isAccessible() {
        return status == FileStatus.UPLOADED || status == FileStatus.PROCESSED;
    }
    
    /**
     * 检查文件是否已过期
     * @return 是否已过期
     */
    public boolean isExpired() {
        return expiresAt != null && LocalDateTime.now().isAfter(expiresAt);
    }
    
    /**
     * 检查是否为图片文件
     * @return 是否为图片
     */
    public boolean isImage() {
        return fileType == FileType.IMAGE;
    }
    
    /**
     * 检查是否为视频文件
     * @return 是否为视频
     */
    public boolean isVideo() {
        return fileType == FileType.VIDEO;
    }
    
    /**
     * 检查是否为音频文件
     * @return 是否为音频
     */
    public boolean isAudio() {
        return fileType == FileType.AUDIO;
    }
    
    /**
     * 获取文件大小的可读格式
     * @return 文件大小字符串
     */
    public String getReadableFileSize() {
        if (fileSize == null || fileSize == 0) {
            return "0 B";
        }
        
        String[] units = {"B", "KB", "MB", "GB", "TB"};
        int digitGroups = (int) (Math.log10(fileSize) / Math.log10(1024));
        
        return String.format("%.1f %s", 
                fileSize / Math.pow(1024, digitGroups), 
                units[digitGroups]);
    }
    
    // 手动添加getter和setter方法以解决编译问题
    public String getMerchantId() {
        return merchantId;
    }
    
    public String getId() {
        return id;
    }
    
    public String getFilePath() {
        return filePath;
    }
    
    public String getThumbnailPath() {
        return thumbnailPath;
    }
    
    public Boolean getIsPublic() {
        return isPublic;
    }
    
    public Long getAccessCount() {
        return accessCount;
    }
    
    public void setLastAccessedAt(LocalDateTime lastAccessedAt) {
        this.lastAccessedAt = lastAccessedAt;
    }
    
    public String getFileName() {
        return fileName;
    }
    
    public FileType getFileType() {
        return fileType;
    }
    
    public String getMediaInfo() {
        return mediaInfo;
    }
    
    public void setMediaInfo(String mediaInfo) {
        this.mediaInfo = mediaInfo;
    }
    
    public void setThumbnailPath(String thumbnailPath) {
        this.thumbnailPath = thumbnailPath;
    }
    
    public void setThumbnailUrl(String thumbnailUrl) {
        this.thumbnailUrl = thumbnailUrl;
    }
    
    // 添加缺失的setter方法
    public void setId(String id) {
        this.id = id;
    }
    
    public void setProcessStatus(ProcessStatus processStatus) {
        this.processStatus = processStatus;
    }
    
    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }
    
    public void setProcessResult(String processResult) {
        this.processResult = processResult;
    }
    
    public void setDeleted(Integer deleted) {
        this.deleted = deleted;
    }
    
    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
    
    public void setAccessCount(Long accessCount) {
        this.accessCount = accessCount;
    }
}